package com.yxx.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.yxx.annotation.AccessLimit;
import com.yxx.annotation.OptLogger;
import com.yxx.annotation.VisitLogger;
import com.yxx.entityModel.vo.Result.PageResult;
import com.yxx.entityModel.vo.Result.ResponseResult;
import com.yxx.entityModel.vo.query.ArticleQuery;
import com.yxx.entityModel.vo.query.PageQuery;
import com.yxx.entityModel.vo.request.ArticleRequest;
import com.yxx.entityModel.vo.request.DeleteRequest;
import com.yxx.entityModel.vo.request.RecommendRequest;
import com.yxx.entityModel.vo.request.TopRequest;
import com.yxx.entityModel.vo.response.*;
import com.yxx.enums.LikeTypeEnum;
import com.yxx.service.ArticleService;
import com.yxx.strategy.context.LikeStrategyContext;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;

import java.util.List;

import static com.yxx.constant.OptTypeConstant.*;

/**
 * 文章模块接口
 * @author yuxiangxun
 * @date 2025/1/21
 * @apiNote
 */
@Slf4j
@RestController
@Api(tags = "文章模块")
public class ArticleController {

    @Resource
    private ArticleService articleService;

    @Resource
    private LikeStrategyContext likeStrategyContext;

    /**
     * 查看后台文章列表
     * @param articleQuery
     * @return
     */
    @ApiOperation(value = "查看后台文章列表")
    @SaCheckPermission("blog:article:list")
    @GetMapping("/admin/article/list")
    public ResponseResult<PageResult<ArticleBackResponse>> listArticleBackVO(ArticleQuery articleQuery){
        return ResponseResult.success(articleService.listAriticleBackVO(articleQuery));
    }

    /**
     * 添加文章
     * @param articleRequest
     * @return
     */
    @OptLogger(value = ADD)
    @ApiOperation(value = "添加文章")
    @SaCheckPermission("blog:article:add")
    @PostMapping("/admin/article/add")
    public ResponseResult addArticle(@Validated @RequestBody ArticleRequest articleRequest){
        articleService.addArticle(articleRequest);
        return ResponseResult.success();
    }

    /**
     * 删除文章
     * @param articleIdList 文章id集合
     * @return {@link ResponseResult<>}
     */
    @OptLogger(value = DELETE)
    @ApiOperation(value = "删除文章")
    @SaCheckPermission("blog:article:delete")
    @DeleteMapping("/admin/article/delete")
    public ResponseResult<?> deleteArticle(@RequestBody List<Integer> articleIdList) {
        articleService.deleteArticle(articleIdList);
        return ResponseResult.success();
    }

    /**
     * 回收或恢复文章
     * @param deleteRequest 逻辑删除
     * @return {@link ResponseResult<>}
     */
    @OptLogger(value = UPDATE)
    @ApiOperation(value = "回收或恢复文章")
    @SaCheckPermission("blog:article:recycle")
    @PutMapping("/admin/article/recycle")
    public ResponseResult<?> updateArticleDelete(@Validated @RequestBody DeleteRequest deleteRequest) {
        articleService.updateArticleDelete(deleteRequest);
        return ResponseResult.success();
    }

    /**
     * 修改文章
     * @param articleRequest 文章信息
     * @return {@link ResponseResult<>}
     */
    @OptLogger(value = UPDATE)
    @ApiOperation(value = "修改文章")
    @SaCheckPermission("blog:article:update")
    @PutMapping("/admin/article/update")
    public ResponseResult<?> updateArticle(@Validated @RequestBody ArticleRequest articleRequest) {
        articleService.updateArticle(articleRequest);
        return ResponseResult.success();
    }
    /**
     * 编辑文章
     * @param articleId 文章id
     * @return {@link  ResponseResult< ArticleInfoResponse >} 后台文章
     */
    @ApiOperation(value = "编辑文章")
    @SaCheckPermission("blog:article:edit")
    @GetMapping("/admin/article/edit/{articleId}")
    public ResponseResult<ArticleInfoResponse> editArticle(@PathVariable("articleId") Integer articleId) {
        return  ResponseResult.success(articleService.editArticle(articleId));
    }

    /**
     * 上传文章图片
     * @param file 文件
     * @return {@link ResponseResult<String>} 文章图片地址
     */
    @OptLogger(value = UPLOAD)
    @ApiOperation(value = "上传文章图片")
    @ApiImplicitParam(name = "file", value = "文章图片", required = true, dataType = "MultipartFile")
    @SaCheckPermission("blog:article:upload")
    @PostMapping("/admin/article/upload")
    public ResponseResult<String> saveArticleImages(@RequestParam("file") MultipartFile file) {
        return ResponseResult.success(articleService.saveArticleImages(file));
    }


    /**
     * 置顶文章
     * @param topRequest 置顶信息
     * @return {@link ResponseResult<>}
     */
    @OptLogger(value = UPDATE)
    @ApiOperation(value = "置顶文章")
    @SaCheckPermission("blog:article:top")
    @PutMapping("/admin/article/top")
    public ResponseResult<?> updateArticleTop(@Validated @RequestBody TopRequest topRequest) {
        articleService.updateArticleTop(topRequest);
        return ResponseResult.success();
    }

    /**
     * 推荐文章
     *
     * @param recommendRequest 推荐信息
     * @return {@link ResponseResult<>}
     */
    @OptLogger(value = UPDATE)
    @ApiOperation(value = "推荐文章")
    @SaCheckPermission("blog:article:recommend")
    @PutMapping("/admin/article/recommend")
    public ResponseResult<?> updateArticleRecommend(@Validated @RequestBody RecommendRequest recommendRequest) {
        articleService.updateArticleRecommend(recommendRequest);
        return ResponseResult.success();
    }

    /**
     * 点赞文章
     * @param articleId 文章id
     * @return {@link ResponseResult<>}
     */
    @SaCheckLogin
    @ApiOperation(value = "点赞文章")
    @AccessLimit(seconds = 60, maxCount = 3)
    @SaCheckPermission("blog:article:like")
    @PostMapping("/article/{articleId}/like")
    public ResponseResult<?> likeArticle(@PathVariable("articleId") Integer articleId) {
        likeStrategyContext.executeLikeStrategy(LikeTypeEnum.ARTICLE, articleId);
        return ResponseResult.success();
    }

    /**
     * 搜索文章
     *
     * @param keyword 关键字
     * @return {@link ResponseResult< ArticleSearchResponse >} 文章列表
     */
    @ApiOperation(value = "搜索文章")
    @GetMapping("/article/search")
    public ResponseResult<List<ArticleSearchResponse>> listArticlesBySearch(String keyword) {
        return ResponseResult.success(articleService.listArticlesBySearch(keyword));
    }

    /**
     * 查看首页文章列表
     *
     * @param pageQuery 分页条件
     * @return {@link ResponseResult< ArticleHomeResponse >}
     */
    @VisitLogger(value = "首页")
    @ApiOperation(value = "查看首页文章列表")
    @GetMapping("/article/list")
    public ResponseResult<PageResult<ArticleHomeResponse>> listArticleHomeVO(PageQuery pageQuery) {
        return ResponseResult.success(articleService.listArticleHomeVO(pageQuery));
    }

    /**
     * 查看文章
     * @param articleId 文章id
     * @return {@link ResponseResult<ArticleResponse>} 首页文章
     */
    @VisitLogger(value = "文章")
    @ApiOperation(value = "查看文章")
    @GetMapping("/article/{articleId}")
    public ResponseResult<ArticleResponse> getArticleHomeById(@PathVariable("articleId") Integer articleId) {
        log.info("type of articleId:{}",articleId.getClass());
        return ResponseResult.success(articleService.getArticleHomeById(articleId));
    }

    /**
     * 查看推荐文章
     * @return {@link ResponseResult< ArticleRecommendResponse >} 推荐文章
     */
    @ApiOperation(value = "查看推荐文章")
    @GetMapping("/article/recommend")
    public ResponseResult<List<ArticleRecommendResponse>> listArticleRecommendVO() {
        return ResponseResult.success(articleService.listArticleRecommendVO());
    }

    /**
     * 查看文章归档
     *
     * @param pageQuery 分页条件
     * @return {@link ResponseResult< ArchiveResponse>} 文章归档列表
     */
    @VisitLogger(value = "归档")
    @ApiOperation(value = "查看文章归档")
    @GetMapping("/archives/list")
    public ResponseResult<PageResult<ArchiveResponse>> listArchiveVO(PageQuery pageQuery) {
        return ResponseResult.success(articleService.listArchiveVO(pageQuery));
    }




}
